<!DOCTYPE html>
<html lang="zh-cn">
  <head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta name="author" content="Zhou Wei <zromyk@163.com>">
  <title>设计模式</title>
  <link rel="shortcut icon" href="/favicon.ico">
  <link rel="stylesheet" href="/style/html/pure.css">
  <link rel="stylesheet" href="/style/html/main.css">
  <link rel="stylesheet" href="https://cdn.staticfile.org/font-awesome/4.7.0/css/font-awesome.css">
  <!-- <link rel="stylesheet" href="https://apps.bdimg.com/libs/highlight.js/9.1.0/styles/default.min.css"> -->
<link rel="stylesheet" href="/style/article/highlight/default.min.css">
<link rel="stylesheet" href="/style/article/pell-1.0.6/dist/pell.css">

</head>
<body>
  <!-- <div id="menu-background"></div> -->
  <div id="menu">
    <div class="pure-menu pure-menu-horizontal">
  <ul class="pure-menu-list block-middle">
    <li class="pure-menu-item">
  <a class="pure-menu-heading" href="/index.html">ZROMYK</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link" href="/index.html">主页</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link" href="/public/archive/index.html">归档</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link" href="/public/download/index.html">下载</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link" href="/public/feedback/index.html">反馈</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link" href="/public/about/index.html">关于我</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link" href="https://github.com/zromyk"><i class="fa fa-github" style="font-size:32px"></i></a>
</li>

  </ul>
</div>

  </div>
  <div id="layout">
    <div class="content">
      <div id="nav">
    <div id="navigation" class="navigation">
  <ul class="pure-menu-list">
    <li class="pure-menu-item">
  <a class="pure-menu-link nav1" onclick="animateByNav()" href="#_1">设计模式</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav2" onclick="animateByNav()" href="#_2">设计模式的类型</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav2" onclick="animateByNav()" href="#_3">设计模式的六大原则</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav1" onclick="animateByNav()" href="#_4">创建型模式</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav2" onclick="animateByNav()" href="#factory-pattern">工厂模式（Factory Pattern）</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav2" onclick="animateByNav()" href="#abstract-factory-pattern">抽象工厂模式（Abstract Factory Pattern）</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav2" onclick="animateByNav()" href="#singleton-pattern">单例模式（Singleton Pattern）</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav3" onclick="animateByNav()" href="#_5">原始的单例模式</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav4" onclick="animateByNav()" href="#_6">使用局部静态对象来解决存在的两个问题</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav3" onclick="animateByNav()" href="#_7">多线程锁定模式</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav3" onclick="animateByNav()" href="#dclpdouble-checked-locking-pattern">双重检查锁定模式（DCLP，Double-Checked Locking Pattern）</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav3" onclick="animateByNav()" href="#_8">最佳实现</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav2" onclick="animateByNav()" href="#builder-pattern">建造者模式（Builder Pattern）</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav2" onclick="animateByNav()" href="#prototype-pattern">原型模式（Prototype Pattern）</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav1" onclick="animateByNav()" href="#_9">结构型模式</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav2" onclick="animateByNav()" href="#adapter-pattern">适配器模式（Adapter Pattern）</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav2" onclick="animateByNav()" href="#bridge-pattern">桥接模式（Bridge Pattern）</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav2" onclick="animateByNav()" href="#filter-pattern">过滤器模式（Filter Pattern）</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav2" onclick="animateByNav()" href="#composite-pattern">组合模式（Composite Pattern）</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav2" onclick="animateByNav()" href="#decorator-pattern">装饰器模式（Decorator Pattern）</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav2" onclick="animateByNav()" href="#facade-pattern">外观模式（Facade Pattern）</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav2" onclick="animateByNav()" href="#flyweight-pattern">享元模式（Flyweight Pattern）</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav2" onclick="animateByNav()" href="#proxy-pattern">代理模式（Proxy Pattern）</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav1" onclick="animateByNav()" href="#_10">行为型模式</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav2" onclick="animateByNav()" href="#chain-of-responsibility-pattern">责任链模式（Chain of Responsibility Pattern）</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav2" onclick="animateByNav()" href="#command-pattern">命令模式（Command Pattern）</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav2" onclick="animateByNav()" href="#interpreter-pattern">解释器模式（Interpreter Pattern）</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav2" onclick="animateByNav()" href="#iterator-pattern">迭代器模式（Iterator Pattern）</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav2" onclick="animateByNav()" href="#mediator-pattern">中介者模式（Mediator Pattern）</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav2" onclick="animateByNav()" href="#memento-pattern">备忘录模式（Memento Pattern）</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav2" onclick="animateByNav()" href="#observer-pattern">观察者模式（Observer Pattern）</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav2" onclick="animateByNav()" href="#state-pattern">状态模式（State Pattern）</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav2" onclick="animateByNav()" href="#null-object-pattern">空对象模式（Null Object Pattern）</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav2" onclick="animateByNav()" href="#strategy-pattern">策略模式（Strategy Pattern）</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav2" onclick="animateByNav()" href="#template-pattern">模板模式（Template Pattern）</a>
</li>
<li class="pure-menu-item">
  <a class="pure-menu-link nav2" onclick="animateByNav()" href="#visitor-pattern">访问者模式（Visitor Pattern）</a>
</li>

  </ul>
</div>

</div>
<div id="content-articles">
  <h1 id="设计模式" class="content-subhead">设计模式</h1>
  <p>
    <span>2022-06-18</span>
    <span><span class="post-category post-category-cpp">C++</span></span>
    <button id="button-markdownEditor" class="pure-button" onclick="markdownEditor()">启用编辑</button>
    <button id="button-save" class="pure-button" onclick="save()">保存</button>
  </p>
  <div id="content-articles-markdownEditor" style="display: none;">
    <h1>编辑 power by pell</h1>
    <div id="editor" class="pell"></div>
    <div style="margin-top:20px;">
        <h3>Text output:</h3>
        <div id="text-output"></div>
    </div>
    <div style="margin-top:20px;">
        <h3>HTML output:</h3>
        <pre id="html-output"></pre>
    </div>
  </div>
  <div id="content-articles-markdown">
    <h1 id="_1">设计模式</h1>
<h2 id="_2">设计模式的类型</h2>
<p>根据设计模式的参考书 <strong>Design Patterns - Elements of Reusable Object-Oriented Software（中文译名：设计模式 - 可复用的面向对象软件元素）</strong> 中所提到的，总共有 23 种设计模式。</p>
<p>这些模式可以分为三大类：</p>
<p>创建型模式（Creational Patterns）、</p>
<p>结构型模式（Structural Patterns）、</p>
<p>行为型模式（Behavioral Patterns）。</p>
<h2 id="_3">设计模式的六大原则</h2>
<p><strong>1、开闭原则（Open Close Principle）</strong></p>
<p>开闭原则的意思是：<strong>对扩展开放，对修改关闭</strong>。在程序需要进行拓展的时候，不能去修改原有的代码，实现一个热插拔的效果。简言之，是为了使程序的扩展性好，易于维护和升级。想要达到这样的效果，我们需要使用接口和抽象类，后面的具体设计中我们会提到这点。</p>
<p><strong>2、里氏代换原则（Liskov Substitution Principle）</strong></p>
<p>里氏代换原则是面向对象设计的基本原则之一。 里氏代换原则中说，任何基类可以出现的地方，子类一定可以出现。LSP 是继承复用的基石，只有当派生类可以替换掉基类，且软件单位的功能不受到影响时，基类才能真正被复用，而派生类也能够在基类的基础上增加新的行为。里氏代换原则是对开闭原则的补充。实现开闭原则的关键步骤就是抽象化，而基类与子类的继承关系就是抽象化的具体实现，所以里氏代换原则是对实现抽象化的具体步骤的规范。</p>
<p><strong>3、依赖倒转原则（Dependence Inversion Principle）</strong></p>
<p>这个原则是开闭原则的基础，具体内容：针对接口编程，依赖于抽象而不依赖于具体。</p>
<p><strong>4、接口隔离原则（Interface Segregation Principle）</strong></p>
<p>这个原则的意思是：使用多个隔离的接口，比使用单个接口要好。它还有另外一个意思是：降低类之间的耦合度。由此可见，其实设计模式就是从大型软件架构出发、便于升级和维护的软件设计思想，它强调降低依赖，降低耦合。</p>
<p><strong>5、迪米特法则，又称最少知道原则（Demeter Principle）</strong></p>
<p>最少知道原则是指：一个实体应当尽量少地与其他实体之间发生相互作用，使得系统功能模块相对独立。</p>
<p><strong>6、合成复用原则（Composite Reuse Principle）</strong></p>
<p>合成复用原则是指：尽量使用合成/聚合的方式，而不是使用继承。</p>
<div class="pure-table-scrollable"><table class="pure-table pure-table-horizontal">
<thead>
<tr>
<th align="left">序号</th>
<th>模式</th>
<th align="left">描述</th>
<th align="left">包括</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left">1</td>
<td>创建型模式</td>
<td align="left">这些设计模式提供了一种在创建对象的同时隐藏创建逻辑的方式，<br />而不是使用 new 运算符直接实例化对象。<br />这使得程序在判断针对某个给定实例需要创建哪些对象时更加灵活。</td>
<td align="left">工厂模式（Factory Pattern）<br />抽象工厂模式（Abstract Factory Pattern）<br />单例模式（Singleton Pattern）<br />建造者模式（Builder Pattern）<br />原型模式（Prototype Pattern）</td>
</tr>
<tr>
<td align="left">2</td>
<td>结构型模式</td>
<td align="left">这些设计模式关注类和对象的组合。<br />继承的概念被用来组合接口和定义组合对象获得新功能的方式。</td>
<td align="left">适配器模式（Adapter Pattern）<br />桥接模式（Bridge Pattern）<br />过滤器模式（Filter、Criteria Pattern）<br />组合模式（Composite Pattern）<br />装饰器模式（Decorator Pattern）<br />外观模式（Facade Pattern）<br />享元模式（Flyweight Pattern）<br />代理模式（Proxy Pattern）</td>
</tr>
<tr>
<td align="left">3</td>
<td>行为型模式</td>
<td align="left">这些设计模式特别关注对象之间的通信。</td>
<td align="left">责任链模式（Chain of Responsibility Pattern）<br />命令模式（Command Pattern）<br />解释器模式（Interpreter Pattern）<br />迭代器模式（Iterator Pattern）<br />中介者模式（Mediator Pattern）<br />备忘录模式（Memento Pattern）<br />观察者模式（Observer Pattern）<br />状态模式（State Pattern）<br />空对象模式（Null Object Pattern）<br />策略模式（Strategy Pattern）<br />模板模式（Template Pattern）<br />访问者模式（Visitor Pattern）</td>
</tr>
<tr>
<td align="left">4</td>
<td>J2EE 模式</td>
<td align="left">这些设计模式特别关注表示层。<br />这些模式是由 Sun Java Center 鉴定的。</td>
<td align="left">MVC 模式（MVC Pattern）<br />业务代表模式（Business Delegate Pattern）<br />组合实体模式（Composite Entity Pattern）<br />数据访问对象模式（Data Access Object Pattern）<br />前端控制器模式（Front Controller Pattern）<br />拦截过滤器模式（Intercepting Filter Pattern）<br />服务定位器模式（Service Locator Pattern）<br />传输对象模式（Transfer Object Pattern）</td>
</tr>
</tbody>
</table></div>
<h1 id="_4">创建型模式</h1>
<h2 id="factory-pattern">工厂模式（Factory Pattern）</h2>
<p>这种类型的设计模式属于创建型模式，它提供了一种创建对象的最佳方式。</p>
<p>在工厂模式中，我们在创建对象时不会对客户端暴露创建逻辑，并且是通过使用一个共同的接口来指向新创建的对象。</p>
<pre><code class="pre-wrap"><span style="overflow-x: auto; max-width:100%; display:inline;"><code class="language-c++">#include &lt;iostream&gt;
#include &lt;string&gt;

// 创建形状抽象类
class Shape {
 public:
    virtual ~Shape() = default;
    virtual void draw() = 0;
};

// 创建形状实体类
class Rectangle : public Shape {
 public:
    void draw() override { printf(&quot;Rectangle\n&quot;); }
};

class Square : public Shape {
 public:
    void draw() override { printf(&quot;Square\n&quot;); }
};

class Circle : public Shape {
 public:
    void draw() override { printf(&quot;Circle\n&quot;); }
};

// 创建工厂
class Factory {
 public:
    Shape *newShape(std::string name) const {
        if (name == &quot;Rectangle&quot;) { return new Rectangle; }
        else if (name == &quot;Square&quot;) { return new Square; }
        else if (name == &quot;Circle&quot;) { return new Circle; }
        else { return nullptr; }
    }
};

// test
int main(int argc, char *argv[]) {
    {
        Factory factory;

        Shape *rectangle = factory.newShape(&quot;Rectangle&quot;);
        Shape *square = factory.newShape(&quot;Square&quot;);
        Shape *circle = factory.newShape(&quot;Circle&quot;);

        rectangle-&gt;draw();
        square-&gt;draw();
        circle-&gt;draw();

        delete rectangle;
        delete square;
        delete circle;
    }
    return 0;
}
</code></span></code></pre>
<h2 id="abstract-factory-pattern">抽象工厂模式（Abstract Factory Pattern）</h2>
<p>抽象工厂模式（Abstract Factory Pattern）是围绕一个超级工厂创建其他工厂。该超级工厂又称为其他工厂的工厂。这种类型的设计模式属于创建型模式，它提供了一种创建对象的最佳方式。</p>
<p>在抽象工厂模式中，接口是负责创建一个相关对象的工厂，不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象。</p>
<pre><code class="pre-wrap"><span style="overflow-x: auto; max-width:100%; display:inline;"><code class="language-c++">#include &lt;iostream&gt;
#include &lt;string&gt;

// 1. 为形状创建接口（抽象类）和实体类
class Shape {
 public:
    virtual ~Shape() = default;
    virtual void draw() = 0;
};

class Rectangle : public Shape {
 public:
    void draw() override { printf(&quot;Rectangle\n&quot;); }
};

class Square : public Shape {
 public:
    void draw() override { printf(&quot;Square\n&quot;); }
};

class Circle : public Shape {
 public:
    void draw() override { printf(&quot;Circle\n&quot;); }
};

// 2. 为颜色创建接口（抽象类）和实体类
class Color {
 public:
    virtual ~Color() = default;
    virtual void fill() = 0;
};

class Red : public Color {
 public:
    void fill() override { printf(&quot;Red\n&quot;); }
};

class Green : public Color {
 public:
    void fill() override { printf(&quot;Green\n&quot;); }
};

class Blue : public Color {
 public:
    void fill() override { printf(&quot;Blue\n&quot;); }
};

// 3. 为工厂创建接口（抽象类）和实体类
class AbstractFactory {
 public:
    virtual ~AbstractFactory(){};
    virtual Shape *newShape(std::string name) = 0;
    virtual Color *newColor(std::string name) = 0;
};

class ShapeFactory : public AbstractFactory {
 public:
    Shape *newShape(std::string name) override {
        if (name == &quot;Rectangle&quot;) { return new Rectangle; }
        else if (name == &quot;Square&quot;) { return new Square; }
        else if (name == &quot;Circle&quot;) { return new Circle; }
        else { return nullptr; }
    }

    Color *newColor(std::string name) override {
        return nullptr;
    }
};

class ColorFactory : public AbstractFactory {
 public:
    Shape *newShape(std::string name) override {
        return nullptr;
    }

    Color *newColor(std::string name) override {
        if (name == &quot;Red&quot;) { return new Red; }
        else if (name == &quot;Green&quot;) { return new Green; }
        else if (name == &quot;Blue&quot;) { return new Blue; }
        else { return nullptr; }
    }
};

// 4. 创建一个工厂创造器/生成器类，通过传递形状或颜色信息来获取工厂
class FactoryProducer {
 public:
    AbstractFactory *newFactory(std::string name) {
        if (name == &quot;ShapeFactory&quot;) { return new ShapeFactory; }
        else if (name == &quot;ColorFactory&quot;) { return new ColorFactory; }
        else { return nullptr; }
    }
};

// test
int main(int argc, char *argv[]) {
    {
        FactoryProducer factoryProducer;

        AbstractFactory *shapeFactory = factoryProducer.newFactory(&quot;ShapeFactory&quot;);
        AbstractFactory *colorFactory = factoryProducer.newFactory(&quot;ColorFactory&quot;);

        {
            Shape *rectangle = shapeFactory-&gt;newShape(&quot;Rectangle&quot;);
            Shape *square = shapeFactory-&gt;newShape(&quot;Square&quot;);
            Shape *circle = shapeFactory-&gt;newShape(&quot;Circle&quot;);

            rectangle-&gt;draw();
            square-&gt;draw();
            circle-&gt;draw();

            delete circle;
            delete square;
            delete rectangle;
        }

        {
            Color *red = colorFactory-&gt;newColor(&quot;Red&quot;);
            Color *green = colorFactory-&gt;newColor(&quot;Green&quot;);
            Color *blue = colorFactory-&gt;newColor(&quot;Blue&quot;);

            red-&gt;fill();
            green-&gt;fill();
            blue-&gt;fill();

            delete blue;
            delete green;
            delete red;
        }

        delete colorFactory;
        delete shapeFactory;
    }
    return 0;
}
</code></span></code></pre>
<h2 id="singleton-pattern">单例模式（Singleton Pattern）</h2>
<p>这种模式涉及到一个单一的类，该类负责创建自己的对象，同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式，可以直接访问，不需要实例化该类的对象。</p>
<p><strong>注意：</strong></p>
<ul>
<li>1、单例类只能有一个实例。</li>
<li>2、单例类必须自己创建自己的唯一实例。</li>
<li>3、单例类必须给所有其他对象提供这一实例。</li>
</ul>
<h3 id="_5">原始的单例模式</h3>
<pre><code class="pre-wrap"><span style="overflow-x: auto; max-width:100%; display:inline;"><code class="language-c++">// singleton.h
class Singleton
{
public:
    static Singleton *instance();
private:
    static Singleton *pInstance;
    Singleton(){};
    ~Singleton(){};
    Singleton(const Singleton&amp;);
    Singleton&amp; operator=(const Singleton&amp;);
};

// singleton.cpp
Singleton *Singleton::pInstance = nullptr;
Singleton *Singleton::instance()
{
    if (pInstance == nullptr) {
        pInstance = new Singleton;
    }
    return pInstance;
}
</code></span></code></pre>
<h4 id="_6">使用局部静态对象来解决存在的两个问题</h4>
<ol>
<li>刚刚的代码中有两个问题，一个是多线程的情况下可能会出现new两次的情况。</li>
<li>另外一个是程序退出后没有运行析构函数。</li>
</ol>
<h3 id="_7">多线程锁定模式</h3>
<pre><code class="pre-wrap"><span style="overflow-x: auto; max-width:100%; display:inline;"><code class="language-c++">// singleton.h
class Singleton
{
public:
    static Singleton *instance();
private:
    static Singleton *pInstance;
    static pthread_mutex_t mutex;
    Singleton(){};
    ~Singleton(){};
    Singleton(const Singleton&amp;);
    Singleton&amp; operator=(const Singleton&amp;);
};

// singleton.cpp
Singleton *Singleton::pInstance = nullptr;
Singleton *Singleton::instance()
{
    pthread_mutex_lock(&amp;mutex);
    if (pInstance == nullptr) {
        pInstance = new Singleton;
    }
    pthread_mutex_unlock(&amp;mutex);
    return pInstance;
}
</code></span></code></pre>
<p>使用mutex以及静态成员来析构单例。该方案的劣处在于锁导致速度慢，效率低。但是至少是正确的，也能在c++11之前的版本使用。</p>
<h3 id="dclpdouble-checked-locking-pattern">双重检查锁定模式（DCLP，Double-Checked Locking Pattern）</h3>
<pre><code class="pre-wrap"><span style="overflow-x: auto; max-width:100%; display:inline;"><code class="language-c++">// singleton.cpp
Singleton *Singleton::pInstance = nullptr;
Singleton *Singleton::instance()
{
    if (pInstance == nullptr) {
        pthread_mutex_lock(&amp;mutex);
        if (pInstance == nullptr) {
            pInstance = new Singleton;
        }
        pthread_mutex_unlock(&amp;mutex);
    }
    return pInstance;
}
</code></span></code></pre>
<h3 id="_8">最佳实现</h3>
<p>C++11规定了local static在多线程条件下的初始化行为，要求编译器保证了内部静态变量的线程安全性。在C++11标准下，《Effective C++》提出了一种更优雅的单例模式实现，使用函数内的 local static 对象。</p>
<p>这种方法也被称为Meyers’ Singleton。C++0x之后该实现是线程安全的，C++0x之前仍需加锁。</p>
<pre><code class="pre-wrap"><span style="overflow-x: auto; max-width:100%; display:inline;"><code class="language-c++">#if __cplusplus &lt; 201103L
    #error should use C++ 11 implementation
#endif

// singleton.cpp
class Singleton
{
public:
    static Singleton&amp; instance();
private:
    Singleton(){};
    ~Singleton(){};
    Singleton(const Singleton&amp;);
    Singleton&amp; operator=(const Singleton&amp;);
};

Singleton&amp; Singleton::instance()
{
    static Singleton instance;
    return instance;
}
</code></span></code></pre>
<h2 id="builder-pattern">建造者模式（Builder Pattern）</h2>
<p>建造者模式（Builder Pattern）使用多个简单的对象一步一步构建成一个复杂的对象。这种类型的设计模式属于创建型模式，它提供了一种创建对象的最佳方式。</p>
<p>一个 Builder 类会一步一步构造最终的对象。该 Builder 类是独立于其他对象的。</p>
<pre><code class="pre-wrap"><span style="overflow-x: auto; max-width:100%; display:inline;"><code class="language-c++">#include &lt;iostream&gt;
#include &lt;memory&gt;
#include &lt;string&gt;
#include &lt;list&gt;

// 1. 为食物包装创建接口（抽象类）和实体类
class Pack {
 public:
    virtual ~Pack() = default;
    virtual std::string name() { return &quot;Default Pack&quot;; }
};

class Wrapper : public Pack {
 public:
    std::string name() override { return &quot;Wrapper&quot;; }
};

class Bottle : public Pack {
 public:
    std::string name() override { return &quot;Bottle&quot;; }
};

// 2. 为食物条目创建接口（抽象类）和实体类
class Item {
 public:
    virtual ~Item() = default;
    virtual std::string name() = 0;
    virtual Pack getPack() = 0;
    virtual float price() = 0;
};

class Burger : public Item {
 public:
    Pack getPack() override { return wrapper; }
    float price() override = 0;

 private:
    Wrapper wrapper;
};

class ColdDrink : public Item {
 public:
    Pack getPack() override { return bottle; }
    float price() override = 0;

 private:
    Bottle bottle;
};

// 3. 建扩展了 Burger 和 ColdDrink 的实体类
class VegBurger : public Burger {
 public:
    std::string name() override { return &quot;Veg Burger&quot;; }
    float price() override { return 25.0f; };
};

class ChickenBurger : public Burger {
 public:
    std::string name() override { return &quot;Chicken Burger&quot;; }
    float price() override { return 50.5f; };
};

class Coke : public ColdDrink {
 public:
    std::string name() override { return &quot;Coke&quot;; }
    float price() override { return 30.0f; };
};

class Pepsi : public ColdDrink {
 public:
    std::string name() override { return &quot;Pepsi&quot;; }
    float price() override { return 35.0f; };
};

// 4. 创建一个 Meal 类，带有上面定义的 Item 对象
class Meal {
 public:
    void addItem(std::shared_ptr&lt;Item&gt; item) {
        items.push_back(item);
    }

    float getCost() {
        float cost = 0.0f;
        for (auto &amp;item : items) {
            cost += item-&gt;price();
        }
        return cost;
    }

    void showItems() {
        for (auto &amp;item : items) {
            printf(&quot;Item : %s, Pack : %s, Price : %f\n&quot;, item-&gt;name().c_str(), item-&gt;getPack().name().c_str(), item-&gt;price());
        }
    }

 private:
    std::list&lt;std::shared_ptr&lt;Item&gt;&gt; items;
};

// 创建一个 MealBuilder 类，实际的 builder 类负责创建 Meal 对象
class MealBuilder {
 public:
    std::shared_ptr&lt;Meal&gt; prepareVegMeal() {
        std::shared_ptr&lt;Meal&gt; meal = std::make_shared&lt;Meal&gt;();
        std::shared_ptr&lt;VegBurger&gt; vegBurger = std::make_shared&lt;VegBurger&gt;();
        std::shared_ptr&lt;Coke&gt; coke = std::make_shared&lt;Coke&gt;();

        meal-&gt;addItem(vegBurger);
        meal-&gt;addItem(coke);
        return meal;
    }

    std::shared_ptr&lt;Meal&gt; prepareNonVegMeal() {
        std::shared_ptr&lt;Meal&gt; meal = std::make_shared&lt;Meal&gt;();
        std::shared_ptr&lt;ChickenBurger&gt; chickenBurger = std::make_shared&lt;ChickenBurger&gt;();
        std::shared_ptr&lt;Pepsi&gt; pepsi = std::make_shared&lt;Pepsi&gt;();

        meal-&gt;addItem(chickenBurger);
        meal-&gt;addItem(pepsi);
        return meal;
    }
};

// test
int main(int argc, char *argv[]) {
    {
        MealBuilder mealBuilder;

        std::shared_ptr&lt;Meal&gt; vegMeal = mealBuilder.prepareVegMeal();
        printf(&quot;Veg Meal\n&quot;);
        vegMeal-&gt;showItems();
        printf(&quot;Total Cost: %f\n&quot;, vegMeal-&gt;getCost());

        std::shared_ptr&lt;Meal&gt; nonVegMeal = mealBuilder.prepareNonVegMeal();
        printf(&quot;Non-Veg Meal\n&quot;);
        nonVegMeal-&gt;showItems();
        printf(&quot;Total Cost: %f\n&quot;, nonVegMeal-&gt;getCost());
    }
    return 0;
}
</code></span></code></pre>
<h2 id="prototype-pattern">原型模式（Prototype Pattern）</h2>
<p>原型模式（Prototype Pattern）是用于创建重复的对象，同时又能保证性能。这种类型的设计模式属于创建型模式，它提供了一种创建对象的最佳方式之一。</p>
<p>这种模式是实现了一个原型接口，该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时，则采用这种模式。例如，一个对象需要在一个高代价的数据库操作之后被创建。我们可以缓存该对象，在下一个请求时返回它的克隆，在需要的时候更新数据库，以此来减少数据库调用。</p>
<pre><code class="pre-wrap"><span style="overflow-x: auto; max-width:100%; display:inline;"><code class="language-c++">#include &lt;iostream&gt;
#include &lt;string&gt;

// 提供一个抽象克隆基类
class Clone {
 public:
    virtual ~Clone() = default;
    virtual Clone *clone() = 0;
    virtual void show() = 0;
};

class Sheep : public Clone {
 public:
    Sheep(std::string name)
        : name(name) {
    }

    // 关键代码拷贝构造函数
    Sheep(const Sheep &amp;obj) {
        name = obj.name;
    }

    // 关键代码克隆函数，返回 return new Sheep(*this)
    Clone *clone() override {
        return new Sheep(*this); // 注意观察拷贝构造函数的实现, 采用了深拷贝
    }

    void show() override {
        std::cout &lt;&lt; &quot;name: &quot; &lt;&lt; name &lt;&lt; std::endl;
    }

 private:
    std::string name;
};

// test
int main(int argc, char *argv[]) {
    {
        Clone *sheepDolly = new Sheep(&quot;dolly&quot;);
        sheepDolly-&gt;show();

        // 采用原型模式写法
        Clone *sheepPrototype = sheepDolly-&gt;clone();
        sheepPrototype-&gt;show();

        // 不使用原型模式的写法
        // Clones*heepCopy(new Sheep(*sheepDolly)); // 编译错误，无法对抽象类解引用，且解引用后的类不是 Sheep 类
        Clone *sheepCopy = new Sheep(*(dynamic_cast&lt;Sheep*&gt;(sheepDolly)));
        sheepCopy-&gt;show();

        delete sheepCopy;
        delete sheepPrototype;
        delete sheepDolly;
    }
    return 0;
}
</code></span></code></pre>
<h1 id="_9">结构型模式</h1>
<h2 id="adapter-pattern">适配器模式（Adapter Pattern）</h2>
<p>适配器模式（Adapter Pattern）是作为两个不兼容的接口之间的桥梁。这种类型的设计模式属于结构型模式，它结合了两个独立接口的功能。</p>
<p>这种模式涉及到一个单一的类，该类负责加入独立的或不兼容的接口功能。举个真实的例子，读卡器是作为内存卡和笔记本之间的适配器。您将内存卡插入读卡器，再将读卡器插入笔记本，这样就可以通过笔记本来读取内存卡。</p>
<pre><code class="pre-wrap"><span style="overflow-x: auto; max-width:100%; display:inline;"><code class="language-c++">#include &lt;iostream&gt;
#include &lt;string&gt;

// 1. 为高级媒体播放器创建接口（抽象类）和实体类
class AdvancedMediaPlayer {
 public:
    virtual ~AdvancedMediaPlayer() = default;
    virtual void playVlc(std::string fileName) = 0;
    virtual void playMp4(std::string fileName) = 0;
};

class VlcPlayer : public AdvancedMediaPlayer {
 public:
    void playVlc(std::string fileName) override { printf(&quot;Playing vlc file. Name: %s\n&quot;, fileName.c_str()); }
    void playMp4(std::string fileName) override {}
};

class Mp4Player : public AdvancedMediaPlayer {
 public:
    void playVlc(std::string fileName) override {}
    void playMp4(std::string fileName) override { printf(&quot;Playing mp4 file. Name: %s\n&quot;, fileName.c_str()); }
};

// 2. 为媒体播放器创建接口（抽象类）和实体类
class MediaPlayer {
 public:
    virtual void play(std::string audioType, std::string fileName) = 0;
};

class MediaAdapter : public MediaPlayer {
 public:
    void play(std::string audioType, std::string fileName) override {
        if (audioType == &quot;vlc&quot;) {
            vlcPlayer.playVlc(fileName);
        }
        else if (audioType == &quot;mp4&quot;) {
            mp4Player.playMp4(fileName);
        }
    }

 private:
    VlcPlayer vlcPlayer;
    Mp4Player mp4Player;
};

class AudioPlayer : public MediaPlayer {
 public:
    void play(std::string audioType, std::string fileName) override {
        if (audioType == &quot;mp3&quot;) {
            printf(&quot;Playing mp3 file. Name: %s\n&quot;, fileName.c_str());
        }
        else if (audioType == &quot;vlc&quot; || audioType == &quot;mp4&quot;) {
            mediaAdapter.play(audioType, fileName);
        }
        else {
            printf(&quot;Invalid media %s format not supported.\n&quot;, audioType.c_str());
        }
    }

 private:
    MediaAdapter mediaAdapter;
};

// test
int main(int argc, char *argv[]) {
    {
        AudioPlayer audioPlayer;

        audioPlayer.play(&quot;mp3&quot;, &quot;horizon.mp3&quot;);
        audioPlayer.play(&quot;mp4&quot;, &quot;alone.mp4&quot;);
        audioPlayer.play(&quot;vlc&quot;, &quot;away.vlc&quot;);
        audioPlayer.play(&quot;avi&quot;, &quot;me.avi&quot;);
    }
    return 0;
}
</code></span></code></pre>
<h2 id="bridge-pattern">桥接模式（Bridge Pattern）</h2>
<p>桥接（Bridge）是用于把抽象化与实现化解耦，使得二者可以独立变化。这种类型的设计模式属于结构型模式，它通过提供抽象化和实现化之间的桥接结构，来实现二者的解耦。</p>
<p>这种模式涉及到一个作为桥接的接口，使得实体类的功能独立于接口实现类。这两种类型的类可被结构化改变而互不影响。</p>
<p>我们通过下面的实例来演示桥接模式（Bridge Pattern）的用法。其中，可以使用相同的抽象类方法但是不同的桥接实现类，来画出不同颜色的圆。</p>
<pre><code class="pre-wrap"><span style="overflow-x: auto; max-width:100%; display:inline;"><code class="language-c++">#include &lt;iostream&gt;
#include &lt;string&gt;

// 抽象工具类
class Implement {
 public:
    Implement() {}
    virtual ~Implement() = default;
    virtual void operation() = 0;
};

// 具体工具类
class ConcreteImplement : public Implement {
 public:
    virtual void operation() override {
        std::cout &lt;&lt; &quot;ConcreteImplement::operation()&quot; &lt;&lt; std::endl;
    }
};

// 抽象类
class Abstraction {
 public:
    Abstraction() {}
    virtual ~Abstraction() = default;
    virtual void operation() = 0;
};

// 具体类
class RefinedAbstraction : public Abstraction {
 public:
    RefinedAbstraction(Implement *implement) {
        this-&gt;implement = implement;
    }

    virtual void operation() override {
        std::cout &lt;&lt; &quot;RefinedAbstraction::operation()&quot; &lt;&lt; std::endl;
        implement-&gt;operation();
    }

 private:
    Implement *implement;
};

// test
int main(int argc, char *argv[]) {
    {
        Implement *implement = new ConcreteImplement();
        Abstraction *abstraction = new RefinedAbstraction(implement);
        abstraction-&gt;operation();

        delete abstraction;
        delete implement;
    }
    return 0;
}
</code></span></code></pre>
<h2 id="filter-pattern">过滤器模式（Filter Pattern）</h2>
<p>过滤器模式（Filter Pattern）或标准模式（Criteria Pattern）是一种设计模式，这种模式允许开发人员使用不同的标准来过滤一组对象，通过逻辑运算以解耦的方式把它们连接起来。这种类型的设计模式属于结构型模式，它结合多个标准来获得单一标准。</p>
<pre><code class="pre-wrap"><span style="overflow-x: auto; max-width:100%; display:inline;"><code class="language-c++">#include &lt;iostream&gt;
#include &lt;string&gt;
#include &lt;list&gt;
#include &lt;algorithm&gt;

/***********************************************************************************
#include &lt;algorithm&gt;

// 字符串不区分大小写比较
bool equalsIgnoreCase(const std::string &amp;string1, const std::string &amp;string2)
{
    std::string string1Temp(string1);
    std::string string1Temp(string2);
    std::transform(string1Temp.begin(), string1Temp.end(), string1Temp.begin(), ::toupper);
    std::transform(string1Temp.begin(), string1Temp.end(), string1Temp.begin(), ::toupper);
    return string1Temp == string1Temp;
}
***********************************************************************************/

// 1. 为个人创建实体类
class Person {
 public:
    Person(const std::string &amp;name, const std::string &amp;gender, const std::string &amp;maritalStatus)
        : name(name),
          gender(gender),
          maritalStatus(maritalStatus) {}

    std::string getName() const { return name; }
    std::string getGender() const { return gender; }
    std::string getMaritalStatus() const { return maritalStatus; }

    bool operator==(const Person &amp;person) {
        return (name == person.name) &amp;&amp; (gender == person.gender) &amp;&amp; (maritalStatus == person.maritalStatus);
    }

 private:
    std::string name;
    std::string gender;
    std::string maritalStatus;
};

// 2. 为标准创建接口（抽象类）和实体类
class Criteria {
 public:
    virtual ~Criteria() = default;
    virtual std::list&lt;Person&gt; meetCriteria(const std::list&lt;Person&gt; &amp;persons) = 0;
};

// 男性
class CriteriaMale : public Criteria {
 public:
    std::list&lt;Person&gt; meetCriteria(const std::list&lt;Person&gt; &amp;persons) override {
        std::list&lt;Person&gt; malePersons;
        for (auto &amp;person : persons) {
            std::string stringTemp(person.getGender());
            std::transform(stringTemp.begin(), stringTemp.end(), stringTemp.begin(), ::toupper);
            if (stringTemp == &quot;MALE&quot;) {
                malePersons.push_back(person);
            }
        }
        return malePersons;
    }
};

// 女性
class CriteriaFemale : public Criteria {
 public:
    std::list&lt;Person&gt; meetCriteria(const std::list&lt;Person&gt; &amp;persons) override {
        std::list&lt;Person&gt; malePersons;
        for (auto &amp;person : persons) {
            std::string stringTemp(person.getGender());
            std::transform(stringTemp.begin(), stringTemp.end(), stringTemp.begin(), ::toupper);
            if (stringTemp == &quot;FEMALE&quot;) {
                malePersons.push_back(person);
            }
        }
        return malePersons;
    }
};

// 单身
class CriteriaSingle : public Criteria {
 public:
    std::list&lt;Person&gt; meetCriteria(const std::list&lt;Person&gt; &amp;persons) override {
        std::list&lt;Person&gt; malePersons;
        for (auto &amp;person : persons) {
            std::string stringTemp(person.getMaritalStatus());
            std::transform(stringTemp.begin(), stringTemp.end(), stringTemp.begin(), ::toupper);
            if (stringTemp == &quot;SINGLE&quot;) {
                malePersons.push_back(person);
            }
        }
        return malePersons;
    }
};

// 与 标准
class AndCriteria : public Criteria {
 public:
    AndCriteria(Criteria &amp;criteria, Criteria &amp;otherCriteria)
        : criteria(criteria),
          otherCriteria(otherCriteria) {}

    std::list&lt;Person&gt; meetCriteria(const std::list&lt;Person&gt; &amp;persons) override {
        std::list&lt;Person&gt; firstCriteriaPersons = criteria.meetCriteria(persons);
        return otherCriteria.meetCriteria(firstCriteriaPersons);
    }

 private:
    Criteria &amp;criteria;
    Criteria &amp;otherCriteria;
};

// 或 标准
class OrCriteria : public Criteria {
 public:
    OrCriteria(Criteria &amp;criteria, Criteria &amp;otherCriteria)
        : criteria(criteria),
          otherCriteria(otherCriteria) {}

    std::list&lt;Person&gt; meetCriteria(const std::list&lt;Person&gt; &amp;persons) override {
        std::list&lt;Person&gt; firstCriteriaItems = criteria.meetCriteria(persons);
        std::list&lt;Person&gt; otherCriteriaItems = otherCriteria.meetCriteria(persons);
        for (auto &amp;person : otherCriteriaItems) {
            if (std::find(firstCriteriaItems.begin(), firstCriteriaItems.end(), person) != firstCriteriaItems.end()) {
                firstCriteriaItems.push_back(person);
            }
        }
        return firstCriteriaItems;
    }

 private:
    Criteria &amp;criteria;
    Criteria &amp;otherCriteria;
};

// 使用不同的标准（Criteria）和它们的结合来过滤 Person 对象的列表
void printPersons(std::list&lt;Person&gt; persons) {
    for (auto &amp;person : persons) {
        printf(&quot;Person : [ Name : %s, Gender : %s, Marital Status : %s ]\n&quot;,
               person.getName().c_str(),
               person.getGender().c_str(),
               person.getMaritalStatus().c_str());
    }
}

int main(int argc, char *argv[]) {
    {
        std::list&lt;Person&gt; persons;
        persons.push_back(Person(&quot;Robert&quot;, &quot;Male&quot;, &quot;Single&quot;));
        persons.push_back(Person(&quot;John&quot;, &quot;Male&quot;, &quot;Married&quot;));
        persons.push_back(Person(&quot;Laura&quot;, &quot;Female&quot;, &quot;Married&quot;));
        persons.push_back(Person(&quot;Diana&quot;, &quot;Female&quot;, &quot;Single&quot;));
        persons.push_back(Person(&quot;Mike&quot;, &quot;Male&quot;, &quot;Single&quot;));
        persons.push_back(Person(&quot;Bobby&quot;, &quot;Male&quot;, &quot;Single&quot;));

        CriteriaMale male;
        CriteriaFemale female;
        CriteriaSingle single;
        AndCriteria singleMale(single, male);
        OrCriteria singleOrFemale(single, female);

        printf(&quot;Males: \n&quot;);
        printPersons(male.meetCriteria(persons));

        printf(&quot;\nFemales: \n&quot;);
        printPersons(female.meetCriteria(persons));

        printf(&quot;\nSingle Males: \n&quot;);
        printPersons(singleMale.meetCriteria(persons));

        printf(&quot;\nSingle Or Females: \n&quot;);
        printPersons(singleOrFemale.meetCriteria(persons));
    }
    return 0;
}
</code></span></code></pre>
<h2 id="composite-pattern">组合模式（Composite Pattern）</h2>
<p>组合模式（Composite Pattern），又叫部分整体模式，是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象，用来表示部分以及整体层次。这种类型的设计模式属于结构型模式，它创建了对象组的树形结构。</p>
<p>这种模式创建了一个包含自己对象组的类。该类提供了修改相同对象组的方式。</p>
<p>我们通过下面的实例来演示组合模式的用法。实例演示了一个组织中员工的层次结构。</p>
<pre><code class="pre-wrap"><span style="overflow-x: auto; max-width:100%; display:inline;"><code class="language-c++">#include &lt;iostream&gt;
#include &lt;memory&gt;
#include &lt;string&gt;
#include &lt;list&gt;

// 1. 创建 Employee 类，该类带有 Employee 对象的列表
class Employee {
 public:
    Employee(std::string name, std::string dept, int salary)
        : name(name), dept(dept), salary(salary) {
    }

    virtual ~Employee() = default;

    void add(std::shared_ptr&lt;Employee&gt; e) {
        subordinates.emplace_back(e);
    }

    void remove(std::shared_ptr&lt;Employee&gt; e) {
        subordinates.remove(e);
    }

    std::list&lt;std::shared_ptr&lt;Employee&gt;&gt; getSubordinates() {
        return subordinates;
    }

    bool operator==(const Employee &amp;e) {
        return (name == e.name) &amp;&amp; (dept == e.dept) &amp;&amp; (salary == e.salary);
    }

    void showInfo() {
        printf(&quot;Employee :[ name : %s, dept : %s, salary : %d ]\n&quot;, name.c_str(), dept.c_str(), salary);
    }

    void showTree() {
        showInfo();
        for (auto &amp;employee : subordinates) {
            employee-&gt;showTree();
        }
    }

 private:
    std::string name;
    std::string dept;
    int salary;
    std::list&lt;std::shared_ptr&lt;Employee&gt;&gt; subordinates;
};

// test 使用 Employee 类来创建和打印员工的层次结构
int main(int argc, char *argv[]) {
    {
        std::shared_ptr&lt;Employee&gt; CEO = std::make_shared&lt;Employee&gt;(&quot;John&quot;, &quot;CEO&quot;, 30000);
        std::shared_ptr&lt;Employee&gt; headSales = std::make_shared&lt;Employee&gt;(&quot;Robert&quot;, &quot;Head Sales&quot;, 20000);         // 头部销售
        std::shared_ptr&lt;Employee&gt; salesExecutive1 = std::make_shared&lt;Employee&gt;(&quot;Richard&quot;, &quot;Sales&quot;, 10000);       // 销售主管1
        std::shared_ptr&lt;Employee&gt; salesExecutive2 = std::make_shared&lt;Employee&gt;(&quot;Rob&quot;, &quot;Sales&quot;, 10000);           // 销售主管2
        std::shared_ptr&lt;Employee&gt; headMarketing = std::make_shared&lt;Employee&gt;(&quot;Michel&quot;, &quot;Head Marketing&quot;, 20000); // 头部经销
        std::shared_ptr&lt;Employee&gt; clerk1 = std::make_shared&lt;Employee&gt;(&quot;Laura&quot;, &quot;Marketing&quot;, 10000);              // 店员1
        std::shared_ptr&lt;Employee&gt; clerk2 = std::make_shared&lt;Employee&gt;(&quot;Bob&quot;, &quot;Marketing&quot;, 10000);                // 店员2

        CEO-&gt;add(headSales);
        CEO-&gt;add(headMarketing);
        headSales-&gt;add(salesExecutive1);
        headSales-&gt;add(salesExecutive2);
        headMarketing-&gt;add(clerk1);
        headMarketing-&gt;add(clerk2);

        // 打印该组织的所有员工
        CEO-&gt;showTree();
    }
    return 0;
}
</code></span></code></pre>
<h2 id="decorator-pattern">装饰器模式（Decorator Pattern）</h2>
<p>装饰器模式（Decorator Pattern）允许向一个现有的对象添加新的功能，同时又不改变其结构。这种类型的设计模式属于结构型模式，它是作为现有的类的一个包装。</p>
<p>这种模式创建了一个装饰类，用来包装原有的类，并在保持类方法签名完整性的前提下，提供了额外的功能。</p>
<p>我们通过下面的实例来演示装饰器模式的用法。其中，我们将把一个形状装饰上不同的颜色，同时又不改变形状类。</p>
<pre><code class="pre-wrap"><span style="overflow-x: auto; max-width:100%; display:inline;"><code class="language-c++">#include &lt;iostream&gt;
#include &lt;string&gt;

// 1. 为形状创建和实现接口的实体类
class Shape {
 public:
    virtual ~Shape() = default;
    virtual void draw() = 0;
};

class Rectangle : public Shape {
 public:
    void draw() override { printf(&quot;Rectangle\n&quot;); }
};

class Square : public Shape {
 public:
    void draw() override { printf(&quot;Square\n&quot;); }
};

class Circle : public Shape {
 public:
    void draw() override { printf(&quot;Circle\n&quot;); }
};

// 2. 创建实现了 Shape 接口的抽象装饰类和实体类
class ShapeDecorator : public Shape {
 public:
    ShapeDecorator(Shape &amp;decoratedShape)
        : decoratedShape(decoratedShape) {}
    ShapeDecorator(Shape &amp;&amp;decoratedShape)
        : decoratedShape(decoratedShape) {}

    void draw() override {
        decoratedShape.draw();
        printf(&quot;Border Color: default\n&quot;);
    }

 protected:
    Shape &amp;decoratedShape;
};

class RedShapeDecorator : public ShapeDecorator {
 public:
    RedShapeDecorator(Shape &amp;decoratedShape)
        : ShapeDecorator(decoratedShape) {}
    RedShapeDecorator(Shape &amp;&amp;decoratedShape)
        : ShapeDecorator(decoratedShape) {}

    void draw() override {
        decoratedShape.draw();
        printf(&quot;Border Color: Red\n&quot;);
    }
};

// test 使用 RedShapeDecorator 来装饰 Shape 对象
int main(int argc, char *argv[]) {
    {
        printf(&quot;Circle with normal border: &quot;);
        Circle circle;
        circle.draw();

        printf(&quot;Rectangle with normal border: &quot;);
        Rectangle rectangle;
        rectangle.draw();
        printf(&quot;\n&quot;);

        printf(&quot;Circle of red border: &quot;);
        RedShapeDecorator redCircle(circle);
        redCircle.draw();

        printf(&quot;Rectangle of red border: &quot;);
        RedShapeDecorator redRectangle(rectangle);
        redRectangle.draw();
        printf(&quot;\n&quot;);
    }
    return 0;
}
</code></span></code></pre>
<h2 id="facade-pattern">外观模式（Facade Pattern）</h2>
<p>外观模式（Facade Pattern）隐藏系统的复杂性，并向客户端提供了一个客户端可以访问系统的接口。这种类型的设计模式属于结构型模式，它向现有的系统添加一个接口，来隐藏系统的复杂性。</p>
<p>这种模式涉及到一个单一的类，该类提供了客户端请求的简化方法和对现有系统类方法的委托调用。</p>
<pre><code class="pre-wrap"><span style="overflow-x: auto; max-width:100%; display:inline;"><code class="language-c++">#include &lt;iostream&gt;

// 1. 为形状创建接口（抽象类）和实体类
class Shape {
 public:
    virtual ~Shape() = default;
    virtual void draw() = 0;
};

class Rectangle : public Shape {
 public:
    void draw() override { printf(&quot;Rectangle\n&quot;); }
};

class Square : public Shape {
 public:
    void draw() override { printf(&quot;Square\n&quot;); }
};

class Circle : public Shape {
 public:
    void draw() override { printf(&quot;Circle\n&quot;); }
};

// 2. 创建一个外观类
class ShapeMaker {
 public:
    void drawCircle() {
        circle.draw();
    }
    void drawRectangle() {
        rectangle.draw();
    }
    void drawSquare() {
        square.draw();
    }

 private:
    Rectangle rectangle;
    Square square;
    Circle circle;
};

// test 使用 RedShapeDecorator 来装饰 Shape 对象
int main(int argc, char *argv[]) {
    {
        ShapeMaker shapeMaker;

        shapeMaker.drawCircle();
        shapeMaker.drawRectangle();
        shapeMaker.drawSquare();
    }
    return 0;
}
</code></span></code></pre>
<h2 id="flyweight-pattern">享元模式（Flyweight Pattern）</h2>
<p>享元模式（Flyweight Pattern）主要用于减少创建对象的数量，以减少内存占用和提高性能。这种类型的设计模式属于结构型模式，它提供了减少对象数量从而改善应用所需的对象结构的方式。</p>
<p>享元模式尝试重用现有的同类对象，如果未找到匹配的对象，则创建新对象。我们将通过创建 5 个对象来画出 20 个分布于不同位置的圆来演示这种模式。由于只有 5 种可用的颜色，所以 color 属性被用来检查现有的 <em>Circle</em> 对象。</p>
<pre><code class="pre-wrap"><span style="overflow-x: auto; max-width:100%; display:inline;"><code class="language-c++">#include &lt;iostream&gt;
#include &lt;memory&gt;
#include &lt;string&gt;
#include &lt;unordered_map&gt;

// 1. 为形状创建接口（抽象类）和实体类
class Shape {
 public:
    virtual ~Shape() = default;
    virtual void draw() = 0;
};

class Circle : public Shape {
 public:
    Circle(std::string color)
        : color(color),
          x(0),
          y(0),
          radius(0) {}

    void setX(int x) {
        this-&gt;x = x;
    }

    void setY(int y) {
        this-&gt;y = y;
    }

    void setRadius(int radius) {
        this-&gt;radius = radius;
    }

    void draw() override {
        printf(&quot;Drawing Circle [ color: %s, x: %d, y: %d, radius: %d ]\n&quot;, color.c_str(), x, y, radius);
    }

 private:
    std::string color;
    int x, y, radius;
};

// 2. 创建一个工厂类，生成基于给定信息的实体类的对象
class ShapeFactory {
 public:
    std::shared_ptr&lt;Shape&gt; getCircle(std::string color) {
        auto it = circleMap.find(color);

        if (it == circleMap.end()) {
            std::shared_ptr&lt;Shape&gt; circle = std::make_shared&lt;Circle&gt;(color);
            circleMap.insert(make_pair(color, circle));
            return circle;
        }
        return it-&gt;second;
    }

 private:
    std::unordered_map&lt;std::string, std::shared_ptr&lt;Shape&gt;&gt; circleMap;
};

// test 使用该工厂，通过传递颜色信息来获取实体类的对象
static std::string colors[] = {&quot;Red&quot;, &quot;Green&quot;, &quot;Blue&quot;, &quot;White&quot;, &quot;Black&quot;};

static std::string getRandomColor() {
    return colors[(int)(rand() % (sizeof(colors) / sizeof(colors[0])))];
}

static int getRandomX() {
    return (int)(rand() % 100);
}

static int getRandomY() {
    return (int)(rand() % 100);
}

int main(int argc, char *argv[]) {
    {
        ShapeFactory shapeFactory;

        for (int i = 0; i &lt; 20; ++i) {
            std::string color = getRandomColor();
            std::shared_ptr&lt;Circle&gt; circle = std::dynamic_pointer_cast&lt;Circle, Shape&gt;(shapeFactory.getCircle(color));
            circle-&gt;setX(getRandomX());
            circle-&gt;setY(getRandomY());
            circle-&gt;setRadius(100);
            circle-&gt;draw();
        }
    }
    return 0;
}
</code></span></code></pre>
<h2 id="proxy-pattern">代理模式（Proxy Pattern）</h2>
<p>在代理模式（Proxy Pattern）中，一个类代表另一个类的功能。这种类型的设计模式属于结构型模式。</p>
<p>在代理模式中，我们创建具有现有对象的对象，以便向外界提供功能接口。</p>
<pre><code class="pre-wrap"><span style="overflow-x: auto; max-width:100%; display:inline;"><code class="language-c++">#include &lt;iostream&gt;
#include &lt;memory&gt;
#include &lt;string&gt;

// 1. 为图片创建接口（抽象类）和实体类
class Image {
 public:
    virtual ~Image() = default;
    virtual void display() = 0;
};

class RealImage : public Image {
 public:
    RealImage(std::string fileName)
        : fileName(fileName) {
        loadFromDisk(fileName);
    }

    void display() override {
        printf(&quot;Displaying: %s\n&quot;, fileName.c_str());
    }

    void loadFromDisk(std::string fileName) {
        printf(&quot;Loading: %s\n&quot;, fileName.c_str());
    }

 private:
    std::string fileName;
};

class ProxyImage : public Image {
 public:
    ProxyImage(std::string fileName)
        : realImage(fileName),
          fileName(fileName) {
    }

    void display() override {
        realImage.display();
    }

 private:
    RealImage realImage;
    std::string fileName;
};

// test
int main(int argc, char *argv[]) {
    {
        ProxyImage proxyImage(&quot;test_10mb.jpg&quot;); // Loading: test_10mb.jpg

        proxyImage.display(); // Displaying: test_10mb.jpg
        proxyImage.display(); // Displaying: test_10mb.jpg
    }
    return 0;
}
</code></span></code></pre>
<h1 id="_10">行为型模式</h1>
<h2 id="chain-of-responsibility-pattern">责任链模式（Chain of Responsibility Pattern）</h2>
<p>顾名思义，责任链模式（Chain of Responsibility Pattern）为请求创建了一个接收者对象的链。这种模式给予请求的类型，对请求的发送者和接收者进行解耦。这种类型的设计模式属于行为型模式。</p>
<p>在这种模式中，通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求，那么它会把相同的请求传给下一个接收者，依此类推。</p>
<pre><code class="pre-wrap"><span style="overflow-x: auto; max-width:100%; display:inline;"><code class="language-c++">#include &lt;iostream&gt;
#include &lt;string&gt;

// 1. 为记录器创建接口（抽象类）和实体类
class AbstractLogger {
 public:
    enum {
        INFO,
        REPORT,
        ERROR,
    };

 public:
    virtual ~AbstractLogger() = default;

    void setNextLogger(AbstractLogger *nextLogger) {
        this-&gt;nextLogger = nextLogger;
    }

    void logMessage(int level, std::string message) {
        if (this-&gt;level == level) {
            write(message);
        }
        else if (nextLogger != nullptr) {
            nextLogger-&gt;logMessage(level, message);
        }
    }

 protected:
    virtual void write(std::string message) = 0;

    int level;
    AbstractLogger *nextLogger; // 责任链中的下一个元素
};

class InfoLogger : public AbstractLogger {
 public:
    InfoLogger(int level) {
        this-&gt;level = level;
    }

 protected:
    void write(std::string message) override {
        printf(&quot;InfoLogger: %s\n&quot;, message.c_str());
    }
};

class ReportLogger : public AbstractLogger {
 public:
    ReportLogger(int level) {
        this-&gt;level = level;
    }

 protected:
    void write(std::string message) override {
        printf(&quot;ReportLogger: %s\n&quot;, message.c_str());
    }
};

class ErrorLogger : public AbstractLogger {
 public:
    ErrorLogger(int level) {
        this-&gt;level = level;
    }

 protected:
    void write(std::string message) override {
        printf(&quot;ErrorLogger: %s\n&quot;, message.c_str());
    }
};

// test
static AbstractLogger &amp;getChainOfLoggers() {

    static ErrorLogger errorLogger(AbstractLogger::ERROR);
    static ReportLogger reportLogger(AbstractLogger::REPORT);
    static InfoLogger infoLogger(AbstractLogger::INFO);

    reportLogger.setNextLogger(&amp;infoLogger);
    errorLogger.setNextLogger(&amp;reportLogger);
    return errorLogger;
}

int main(int argc, char *argv[]) {
    {
        AbstractLogger &amp;loggerChain = getChainOfLoggers();

        loggerChain.logMessage(AbstractLogger::ERROR, &quot;This is an ERROR information.&quot;);
        loggerChain.logMessage(AbstractLogger::REPORT, &quot;This is a REPORT information.&quot;);
        loggerChain.logMessage(AbstractLogger::INFO, &quot;This is an INFO information.&quot;);
    }
    return 0;
}
</code></span></code></pre>
<h2 id="command-pattern">命令模式（Command Pattern）</h2>
<p>命令模式（Command Pattern）是一种数据驱动的设计模式，它属于行为型模式。请求以命令的形式包裹在对象中，并传给调用对象。调用对象寻找可以处理该命令的合适的对象，并把该命令传给相应的对象，该对象执行命令。</p>
<pre><code class="pre-wrap"><span style="overflow-x: auto; max-width:100%; display:inline;"><code class="language-c++">#include &lt;iostream&gt;
#include &lt;memory&gt;
#include &lt;string&gt;
#include &lt;list&gt;

// 1. 为请求创建实体类
class Stock {
 public:
    void buy() {
        printf(&quot;Stock [ Name: %s, Quantity: %d ] bought\n&quot;, name.c_str(), quantity);
    }
    void sell() {
        printf(&quot;Stock [ Name: %s, Quantity: %d ] sold\n&quot;, name.c_str(), quantity);
    }

 private:
    std::string name = &quot;ABC&quot;;
    int quantity = 10;
};

// 2. 为命令创建接口（抽象类）和实体类
class Order {
 public:
    virtual ~Order() = default;
    virtual void execute() = 0;
};

class BuyStock : public Order {
 public:
    BuyStock(Stock abcStock)
        : abcStock(abcStock) {
    }

    void execute() override {
        abcStock.buy();
    }

 private:
    Stock abcStock;
};

class SellStock : public Order {
 public:
    SellStock(Stock abcStock)
        : abcStock(abcStock) {
    }

    void execute() override {
        abcStock.sell();
    }

 private:
    Stock abcStock;
};

// 3. 创建命令调用类
class Broker {
 public:
    void takeOrder(std::shared_ptr&lt;Order&gt; order) {
        orderList.push_back(order);
    }

    void placeOrders() {
        for (auto &amp;order : orderList) {
            order-&gt;execute();
        }
        orderList.clear();
    }

 private:
    std::list&lt;std::shared_ptr&lt;Order&gt;&gt; orderList;
};

// test
int main(int argc, char *argv[]) {
    {
        Stock abcStock;

        std::shared_ptr&lt;Order&gt; buyStockOrder = std::make_shared&lt;BuyStock&gt;(abcStock);
        std::shared_ptr&lt;Order&gt; sellStockOrder =  std::make_shared&lt;SellStock&gt;(abcStock);

        Broker broker;
        broker.takeOrder(buyStockOrder);
        broker.takeOrder(sellStockOrder);

        broker.placeOrders();
    }
    return 0;
}
</code></span></code></pre>
<h2 id="interpreter-pattern">解释器模式（Interpreter Pattern）</h2>
<p>解释器模式（Interpreter Pattern）提供了评估语言的语法或表达式的方式，它属于行为型模式。这种模式实现了一个表达式接口，该接口解释一个特定的上下文。这种模式被用在 SQL 解析、符号处理引擎等。</p>
<pre><code class="pre-wrap"><span style="overflow-x: auto; max-width:100%; display:inline;"><code class="language-c++">#include &lt;iostream&gt;
#include &lt;memory&gt;
#include &lt;string&gt;

// 1. 为表达式创建接口（抽象类）和实体类
class Expression {
 public:
    virtual ~Expression() = default;
    virtual bool interpret(std::string context) = 0;
};

class TerminalExpression : public Expression {
 public:
    TerminalExpression(std::string data)
        : data(data) {
    }

    bool interpret(std::string context) override {
        // https://www.techiedelight.com/zh/check-if-a-string-contains-another-string-in-cpp/
        if (context.find(data) != std::string::npos) {
            return true;
        }
        return false;
    }

 private:
    std::string data;
};

class OrExpression : public Expression {
 public:
    OrExpression(std::shared_ptr&lt;Expression&gt; expr1, std::shared_ptr&lt;Expression&gt; expr2)
        : expr1(expr1), expr2(expr2) {
    }

    bool interpret(std::string context) override {
        return expr1-&gt;interpret(context) || expr2-&gt;interpret(context);
    }

 private:
    std::shared_ptr&lt;Expression&gt; expr1;
    std::shared_ptr&lt;Expression&gt; expr2;
};

class AndExpression : public Expression {
 public:
    AndExpression(std::shared_ptr&lt;Expression&gt; expr1, std::shared_ptr&lt;Expression&gt; expr2)
        : expr1(expr1), expr2(expr2) {
    }

    bool interpret(std::string context) override {
        return expr1-&gt;interpret(context) &amp;&amp; expr2-&gt;interpret(context);
    }

 private:
    std::shared_ptr&lt;Expression&gt; expr1;
    std::shared_ptr&lt;Expression&gt; expr2;
};

// test
// 规则：Robert 和 John 是男性
static std::shared_ptr&lt;Expression&gt; getMaleExpression() {
    std::shared_ptr&lt;Expression&gt; robert = std::make_shared&lt;TerminalExpression&gt;(&quot;Robert&quot;);
    std::shared_ptr&lt;Expression&gt; john = std::make_shared&lt;TerminalExpression&gt;(&quot;John&quot;);
    return std::make_shared&lt;OrExpression&gt;(robert, john);
}

// 规则：Julie 是一个已婚的女性
static std::shared_ptr&lt;Expression&gt; getMarriedWomanExpression() {
    std::shared_ptr&lt;Expression&gt; julie = std::make_shared&lt;TerminalExpression&gt;(&quot;Julie&quot;);
    std::shared_ptr&lt;Expression&gt; married = std::make_shared&lt;TerminalExpression&gt;(&quot;Married&quot;);
    return std::make_shared&lt;AndExpression&gt;(julie, married);
}

int main(int argc, char *argv[]) {
    {
        std::shared_ptr&lt;Expression&gt; isMale = getMaleExpression();
        std::shared_ptr&lt;Expression&gt; isMarriedWoman = getMarriedWomanExpression();

        std::cout &lt;&lt; &quot;John is male? &quot; &lt;&lt; isMale-&gt;interpret(&quot;John&quot;) &lt;&lt; std::endl;
        std::cout &lt;&lt; &quot;Julie is a married women? &quot; &lt;&lt; isMarriedWoman-&gt;interpret(&quot;Married Julie&quot;) &lt;&lt; std::endl;
    }
    return 0;
}
</code></span></code></pre>
<h2 id="iterator-pattern">迭代器模式（Iterator Pattern）</h2>
<p>迭代器模式（Iterator Pattern）是 Java 和 .Net 编程环境中非常常用的设计模式。这种模式用于顺序访问集合对象的元素，不需要知道集合对象的底层表示。</p>
<pre><code class="pre-wrap"><span style="overflow-x: auto; max-width:100%; display:inline;"><code class="language-c++">#include &lt;iostream&gt;
#include &lt;memory&gt;
#include &lt;string&gt;
#include &lt;vector&gt;

template&lt;class T&gt;
class Iterator;
template&lt;class T&gt;
class Container;

template &lt;class T&gt;
class Iterator{
 public:
    Iterator&lt;T&gt;()
        : ptr(nullptr) {
    }
    ~Iterator&lt;T&gt;() {}

    T &amp;operator*() const {
        return *this-&gt;ptr;
    }

    Iterator&lt;T&gt; &amp;operator++() {
        this-&gt;ptr++;
        return *this;
    }

    Iterator&lt;T&gt; operator++(int) {
        Iterator&lt;T&gt; temp(*this);
        ++(*this);
        return temp;
    }

    // Iterator&lt;T&gt; &amp;obj         只能接收左值
    // const Iterator&lt;T&gt; &amp;obj   可以接收左值和右值
    // Iterator&lt;T&gt; &amp;&amp;obj        只能接收右值
    // const Iterator&lt;T&gt; &amp;&amp;obj  没有意义
    bool operator!=(const Iterator&lt;T&gt; &amp;obj) {
        return this-&gt;ptr != obj.ptr;
    }

 private:
    friend class Container&lt;T&gt;;
    T *ptr;
};

template &lt;class T&gt;
class Container {
 public:
    Container(int size = 0, int capacity = 32)
        : ptr(nullptr), size(size), capacity(capacity) {
        recapacity(capacity);
    }

    Iterator&lt;T&gt; begin() {
        beginIter.ptr = ptr;
        return beginIter;
    }

    Iterator&lt;T&gt; end() {
        endIter.ptr = ptr + size;
        return endIter;
    }

    void push_back(T t) {
        if (size &gt;= capacity - 1) {
            recapacity(capacity * 2);
        }
        ptr[size++] = t;
    }

 private:
    void recapacity(int capacity = 32) {
        T *ptrTemp = new T[capacity];
        for (int i = 0; i &lt; capacity &amp;&amp; i &lt; size; ++i) {
            ptrTemp[i] = ptr[i];
        }
        delete[] ptr;
        ptr = ptrTemp;
        this-&gt;capacity = capacity;
    }

    T *ptr;
    int size;
    int capacity;
    Iterator&lt;T&gt; beginIter;
    Iterator&lt;T&gt; endIter;
};

// test
int main(int argc, char *argv[]) {
    {
        Container&lt;std::string&gt; container;
        container.push_back(std::string(&quot;Robert&quot;));
        container.push_back(std::string(&quot;John&quot;));
        container.push_back(std::string(&quot;Julie&quot;));
        container.push_back(std::string(&quot;Lora&quot;));

        for (Iterator&lt;std::string&gt; it = container.begin(); it != container.end(); ++it) {
            std::cout &lt;&lt; *it &lt;&lt; std::endl;
        }
    }
    return 0;
}

</code></span></code></pre>
<h2 id="mediator-pattern">中介者模式（Mediator Pattern）</h2>
<p>中介者模式（Mediator Pattern）是用来降低多个对象和类之间的通信复杂性。这种模式提供了一个中介类，该类通常处理不同类之间的通信，并支持松耦合，使代码易于维护。中介者模式属于行为型模式。</p>
<pre><code class="pre-wrap"><span style="overflow-x: auto; max-width:100%; display:inline;"><code class="language-c++">#include &lt;iostream&gt;
#include &lt;string&gt;

class ChatRoom {
 public:
    static void showMessage(std::string name, std::string message) {
        std::cout &lt;&lt; &quot; [&quot; + name + &quot;] : &quot; + message &lt;&lt; std::endl;
    }
};

class User {
 public:
    User(std::string name) {
        this-&gt;name = name;
    }

    void setName(std::string name) {
        this-&gt;name = name;
    }

    std::string getName() {
        return name;
    }

    void sendMessage(std::string message) {
        ChatRoom::showMessage(name, message);
    }

 private:
    std::string name;
};

// test
int main(int argc, char *argv[]) {
    {
        User robert(&quot;Robert&quot;);
        User john(&quot;John&quot;);

        robert.sendMessage(&quot;Hi! John!&quot;);
        john.sendMessage(&quot;Hello! Robert!&quot;);
    }
    return 0;
}
</code></span></code></pre>
<h2 id="memento-pattern">备忘录模式（Memento Pattern）</h2>
<p>备忘录模式（Memento Pattern）保存一个对象的某个状态，以便在适当的时候恢复对象。备忘录模式属于行为型模式。</p>
<pre><code class="pre-wrap"><span style="overflow-x: auto; max-width:100%; display:inline;"><code class="language-c++">#include &lt;iostream&gt;
#include &lt;string&gt;
#include &lt;list&gt;

// 1. 为档案创建实体类
class Archive {
 public:
    Archive(std::string date = &quot;&quot;)
        : date(date) {}

    std::string getDate() {
        return date;
    }

 private:
    std::string date;
};

// 2. 为游戏创建实体类
class Game {
 public:
    void setDate(std::string date) {
        this-&gt;date = date;
    }

    std::string getDate() {
        return date;
    }

    Archive archive() {
        return Archive(date);
    }

    void rollback(Archive &amp;archive) {
        this-&gt;date = archive.getDate();
    }

 private:
    std::string date;
};

// 3. 为档案管理创建实体类
class ArchiveMng {
 public:
    void archive(const Archive &amp;archive) {
        archiveList.push_back(archive);
    }

    int rollback(int index, Archive &amp;archive) {
        std::list&lt;Archive&gt;::iterator it;
        for (it = archiveList.begin(); it != archiveList.end(); ++it) {
            if (index-- == 0) {
                archive = *it;
                return 0;
            }
        }
        return -1;
    }

 private:
    std::list&lt;Archive&gt; archiveList;
};

// test
int main(int argc, char *argv[]) {
    {
        Game game;
        ArchiveMng archiveMng;

        game.setDate(&quot;Date: 2023-6-1&quot;);
        game.setDate(&quot;Date: 2023-7-1&quot;);
        archiveMng.archive(game.archive());

        game.setDate(&quot;Date: 2023-8-1&quot;);
        archiveMng.archive(game.archive());

        game.setDate(&quot;Date: 2023-9-1&quot;);
        std::cout &lt;&lt; &quot;Current State: &quot; &lt;&lt; game.getDate() &lt;&lt; std::endl;

        Archive Archive;
        if (archiveMng.rollback(0, Archive) != 0) {
            return -1;
        }
        game.rollback(Archive);
        std::cout &lt;&lt; &quot;First archive: &quot; &lt;&lt; game.getDate() &lt;&lt; std::endl;

        if (archiveMng.rollback(1, Archive) != 0) {
            return -1;
        }
        game.rollback(Archive);
        std::cout &lt;&lt; &quot;Second archive: &quot; &lt;&lt; game.getDate() &lt;&lt; std::endl;
    }
    return 0;
}
</code></span></code></pre>
<h2 id="observer-pattern">观察者模式（Observer Pattern）</h2>
<p>当对象间存在一对多关系时，则使用观察者模式（Observer Pattern）。比如，当一个对象被修改时，则会自动通知依赖它的对象。观察者模式属于行为型模式。</p>
<pre><code class="pre-wrap"><span style="overflow-x: auto; max-width:100%; display:inline;"><code class="language-c++">#include &lt;iostream&gt;
#include &lt;string&gt;
#include &lt;bitset&gt;
#include &lt;list&gt;

// 抽象观察者（Observer）
class Observer {
 public:
    virtual ~Observer() = default;
    virtual void response(int value) = 0;
};

// 抽象主题（Subject）/ 具体主题（Concrete Subject）
class Subject {
 public:
    int getState() {
        return value;
    }

    void setValue(int value) {
        this-&gt;value = value;
        notifyAllObservers();
    }

    void attach(Observer*observer) {
        observers.push_back(observer);
    }

    void detach(Observer*observer) {
        observers.remove(observer);
    }

    void notifyAllObservers() {
        for (auto observer : observers) {
            observer-&gt;response(value);
        }
    }

 private:
    std::list&lt;Observer*&gt; observers;
    int value;
};

// 具体观察者（Concrete Observer）
class BinaryObserver : public Observer {
 public:
    void response(int value) override {
        std::cout &lt;&lt; &quot;Binary String: &quot; &lt;&lt; (std::bitset&lt;32&gt;)value &lt;&lt; std::endl;
    }
};

class OctalObserver : public Observer {
 public:
    void response(int value) override {
        std::cout &lt;&lt; &quot;Octal String: &quot; &lt;&lt; std::oct &lt;&lt; value &lt;&lt; std::endl;
    }
};

class HexaObserver : public Observer {
 public:
    void response(int value) override {
        std::cout &lt;&lt; &quot;Hex String: &quot; &lt;&lt; std::hex &lt;&lt; value &lt;&lt; std::endl;
    }
};

// test
int main(int argc, char *argv[]) {
    {
        Subject subject;

        HexaObserver hexaObserver;      /* 十六进制观察者 */
        OctalObserver octalObserver;    /* 八进制观察者 */
        BinaryObserver binaryObserver;  /* 二进制观察者 */

        subject.attach(&amp;hexaObserver);
        subject.attach(&amp;octalObserver);
        subject.attach(&amp;binaryObserver);

        std::cout &lt;&lt; &quot;First value change: 15&quot; &lt;&lt; std::endl;
        subject.setValue(15);
        std::cout &lt;&lt; &quot;Second value change: 10&quot; &lt;&lt; std::endl;
        subject.setValue(10);
    }
    return 0;
}
</code></span></code></pre>
<h2 id="state-pattern">状态模式（State Pattern）</h2>
<p>在状态模式（State Pattern）中，类的行为是基于它的状态改变的。这种类型的设计模式属于行为型模式。</p>
<p>在状态模式中，我们创建表示各种状态的对象和一个行为随着状态对象改变而改变的 context 对象。</p>
<pre><code class="pre-wrap"><span style="overflow-x: auto; max-width:100%; display:inline;"><code class="language-c++">#include &lt;iostream&gt;
#include &lt;string&gt;

class Context;

// 抽象状态接口类
class State {
 public:
    virtual ~State() = default;
    virtual void doAction(Context &amp;context) = 0;
    virtual std::string toString() = 0;
};

// 上下文类
class Context {
 public:
    Context() {
        state = nullptr;
    }

    void setState(State *state) {
        this-&gt;state = state;
    }

    State *getState() {
        return state;
    }

 private:
    State *state;
};

// 具体状态接口类
// 要在类 Context 声明后面定义，否则会提示使用了未定义&quot;Context&quot;
class StartState : public State {
 public:
    void doAction(Context &amp;context) override {
        std::cout &lt;&lt; &quot;Player is in start state&quot; &lt;&lt; std::endl;
        context.setState(this);
    }

    std::string toString() override {
        return &quot;Start State&quot;;
    }
};

class StopState : public State {
 public:
    void doAction(Context &amp;context) override {
        std::cout &lt;&lt; &quot;Player is in stop state&quot; &lt;&lt; std::endl;
        context.setState(this);
    }

    std::string toString() override {
        return &quot;Stop State&quot;;
    }
};

// test
int main(int argc, char *argv[]) {
    {
        Context context;

        StartState startState;
        startState.doAction(context);
        std::cout &lt;&lt; context.getState()-&gt;toString() &lt;&lt; std::endl;

        StopState stopState;
        stopState.doAction(context);
        std::cout &lt;&lt; context.getState()-&gt;toString() &lt;&lt; std::endl;
    }
    return 0;
}
</code></span></code></pre>
<h2 id="null-object-pattern">空对象模式（Null Object Pattern）</h2>
<p>在空对象模式（Null Object Pattern）中，一个空对象取代 NULL 对象实例的检查。Null 对象不是检查空值，而是反应一个不做任何动作的关系。这样的 Null 对象也可以在数据不可用的时候提供默认的行为。</p>
<p>在空对象模式中，我们创建一个指定各种要执行的操作的抽象类和扩展该类的实体类，还创建一个未对该类做任何实现的空对象类，该空对象类将无缝地使用在需要检查空值的地方。</p>
<pre><code class="pre-wrap"><span style="overflow-x: auto; max-width:100%; display:inline;"><code class="language-c++">#include &lt;iostream&gt;
#include &lt;memory&gt;
#include &lt;string&gt;

class AbstractCustomer {
 public:
    virtual ~AbstractCustomer() = default;
    virtual bool isNil() = 0;
    virtual std::string getName() = 0;

 protected:
    std::string name;
};

class RealCustomer: public AbstractCustomer {
 public:
    RealCustomer(std::string name) {
        this-&gt;name = name;
    }

    std::string getName() override {
        return name;
    }

    bool isNil() override {
        return false;
    }
};

class NullCustomer: public AbstractCustomer {
 public:
    std::string getName() override {
        return &quot;Not Available in Customer Database&quot;;
    }

    bool isNil() override {
        return true;
    }
};

class CustomerFactory {
 public:
    static constexpr const char *const names[3] = {&quot;Rob&quot;, &quot;Joe&quot;, &quot;Julie&quot;};

    static AbstractCustomer *getCustomer(std::string name) {
        for (int i = 0; i &lt; sizeof(names) / sizeof(names[0]); i++) {
            if (names[i] == name) {
                return new RealCustomer(name);
            }
        }
        return new NullCustomer();
    }
};
constexpr const char *const CustomerFactory::names[3];

// test
int main(int argc, char *argv[]) {
    {
        std::unique_ptr&lt;AbstractCustomer&gt; customer1(CustomerFactory::getCustomer(&quot;Rob&quot;));
        std::unique_ptr&lt;AbstractCustomer&gt; customer2(CustomerFactory::getCustomer(&quot;Bob&quot;));
        std::unique_ptr&lt;AbstractCustomer&gt; customer3(CustomerFactory::getCustomer(&quot;Julie&quot;));
        std::unique_ptr&lt;AbstractCustomer&gt; customer4(CustomerFactory::getCustomer(&quot;Laura&quot;));

        std::cout &lt;&lt; &quot;Customers&quot; &lt;&lt; std::endl;
        std::cout &lt;&lt; customer1-&gt;getName() &lt;&lt; std::endl;
        std::cout &lt;&lt; customer2-&gt;getName() &lt;&lt; std::endl;
        std::cout &lt;&lt; customer3-&gt;getName() &lt;&lt; std::endl;
        std::cout &lt;&lt; customer4-&gt;getName() &lt;&lt; std::endl;
    }
    return 0;
}
</code></span></code></pre>
<h2 id="strategy-pattern">策略模式（Strategy Pattern）</h2>
<p>在策略模式（Strategy Pattern）中，一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。</p>
<p>在策略模式中，我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象。策略对象改变 context 对象的执行算法。</p>
<pre><code class="pre-wrap"><span style="overflow-x: auto; max-width:100%; display:inline;"><code class="language-c++">#include &lt;iostream&gt;
#include &lt;string&gt;

class Strategy {
 public:
    virtual ~Strategy() = default;
    virtual int doOperation(int num1, int num2) const = 0;
};

class OperationAdd : public Strategy {
 public:
    int doOperation(int num1, int num2) const override {
        return num1 + num2;
    }
};

class OperationSubtract : public Strategy {
 public:
    int doOperation(int num1, int num2) const override {
        return num1 - num2;
    }
};

class OperationMultiply : public Strategy {
 public:
    int doOperation(int num1, int num2) const override {
        return num1 * num2;
    }
};

class Context {
 public:
    Context(const Strategy &amp;strategy) {
        this-&gt;strategy = &amp;strategy;
    }

    int executeStrategy(int num1, int num2) {
        return strategy-&gt;doOperation(num1, num2);
    }

 private:
    const Strategy *strategy;
};

// test
int main(int argc, char *argv[]) {
    {
        /* parentheses were disambiguated as a function declaration
            replace parentheses with braces to declare a variable
            与C++中的一条普通规律相符: 尽可能的解释为函数声明。
            明了一个函数 context(), 其返回值为 Context, 它有一个参数，类型是 OperationAdd*/
        // Context context(OperationAdd()); // 这是错误的

        Context context{OperationAdd()};
        std::cout &lt;&lt; &quot;10 + 5 = &quot; &lt;&lt; context.executeStrategy(10, 5) &lt;&lt; std::endl;

        context = Context(OperationSubtract());
        std::cout &lt;&lt; &quot;10 - 5 = &quot; &lt;&lt; context.executeStrategy(10, 5) &lt;&lt; std::endl;

        context = Context(OperationMultiply());
        std::cout &lt;&lt; &quot;10 * 5 = &quot; &lt;&lt; context.executeStrategy(10, 5) &lt;&lt; std::endl;
    }
    return 0;
}
</code></span></code></pre>
<h2 id="template-pattern">模板模式（Template Pattern）</h2>
<p>在模板模式（Template Pattern）中，一个抽象类公开定义了执行它的方法的方式/模板。它的子类可以按需要重写方法实现，但调用将以抽象类中定义的方式进行。这种类型的设计模式属于行为型模式。</p>
<pre><code class="pre-wrap"><span style="overflow-x: auto; max-width:100%; display:inline;"><code class="language-c++">#include &lt;iostream&gt;
#include &lt;string&gt;

class Game {
 public:
    virtual ~Game() = default;
    void play() {
        initialize(); // 初始化游戏
        startPlay();  // 开始游戏
        endPlay();    // 结束游戏
    }

 protected:
    virtual void initialize() = 0;
    virtual void startPlay() = 0;
    virtual void endPlay() = 0;
};

class Cricket : public Game {
 protected:
    void endPlay() override {
        std::cout &lt;&lt; &quot;Cricket Game Finished!&quot; &lt;&lt; std::endl;
    }

    void initialize() override {
        std::cout &lt;&lt; &quot;Cricket Game Initialized! Start playing.&quot; &lt;&lt; std::endl;
    }

    void startPlay() override {
        std::cout &lt;&lt; &quot;Cricket Game Started. Enjoy the game!&quot; &lt;&lt; std::endl;
    }
};

class Football : public Game {
 protected:
    void endPlay() override {
        std::cout &lt;&lt; &quot;Football Game Finished!&quot; &lt;&lt; std::endl;
    }

    void initialize() override {
        std::cout &lt;&lt; &quot;Football Game Initialized! Start playing.&quot; &lt;&lt; std::endl;
    }

    void startPlay() override {
        std::cout &lt;&lt; &quot;Football Game Started. Enjoy the game!&quot; &lt;&lt; std::endl;
    }
};

// test
int main(int argc, char *argv[]) {
    {
        Cricket cricket;
        cricket.play();

        Football football;
        football.play();
    }
    return 0;
}

</code></span></code></pre>
<h2 id="visitor-pattern">访问者模式（Visitor Pattern）</h2>
<p>在访问者模式（Visitor Pattern）中，我们使用了一个访问者类，它改变了元素类的执行算法。通过这种方式，元素的执行算法可以随着访问者改变而改变。这种类型的设计模式属于行为型模式。根据模式，元素对象已接受访问者对象，这样访问者对象就可以处理元素对象上的操作。</p>
<pre><code class="pre-wrap"><span style="overflow-x: auto; max-width:100%; display:inline;"><code class="language-c++">#include &lt;iostream&gt;
#include &lt;memory&gt;
#include &lt;string&gt;
#include &lt;vector&gt;

class Computer;
class Mouse;
class Keyboard;
class Monitor;

// 定义一个表示访问者的接口
class ComputerPartVisitor {
 public:
    virtual ~ComputerPartVisitor() = default;
    virtual void visit(Computer &amp;computer) = 0;
    virtual void visit(Mouse &amp;mouse) = 0;
    virtual void visit(Keyboard &amp;keyboard) = 0;
    virtual void visit(Monitor &amp;monitor) = 0;
};

// 定义一个表示元素的接口
class ComputerPart {
 public:
    virtual ~ComputerPart() = default;
    virtual void accept(ComputerPartVisitor &amp;computerPartVisitor) = 0;
};

// 创建扩展了元素接口的实体类
class Keyboard : public ComputerPart {
 public:
    void accept(ComputerPartVisitor &amp;computerPartVisitor) override {
        computerPartVisitor.visit(*this);
    }
};

class Monitor : public ComputerPart {
 public:
    void accept(ComputerPartVisitor &amp;computerPartVisitor) override {
        computerPartVisitor.visit(*this);
    }
};

class Mouse : public ComputerPart {
 public:
    void accept(ComputerPartVisitor &amp;computerPartVisitor) override {
        computerPartVisitor.visit(*this);
    }
};

class Computer : public ComputerPart {
 public:
    Computer() {
        parts.push_back(std::make_shared&lt;Keyboard&gt;());
        parts.push_back(std::make_shared&lt;Monitor&gt;());
        parts.push_back(std::make_shared&lt;Mouse&gt;());
    }

    void accept(ComputerPartVisitor &amp;computerPartVisitor) {
        for (auto &amp;part : parts) {
            part-&gt;accept(computerPartVisitor);
        }
        computerPartVisitor.visit(*this);
    }

 private:
    std::vector&lt;std::shared_ptr&lt;ComputerPart&gt;&gt; parts;
};

// 创建实现了访问者接口的实体访问者
class ComputerPartDisplayVisitor : public ComputerPartVisitor {
 public:
    void visit(Computer &amp;computer) override {
        std::cout &lt;&lt; &quot;Displaying Computer.&quot; &lt;&lt; std::endl;
    }
    void visit(Mouse &amp;mouse) override {
        std::cout &lt;&lt; &quot;Displaying Mouse.&quot; &lt;&lt; std::endl;
    }
    void visit(Keyboard &amp;keyboard) override {
        std::cout &lt;&lt; &quot;Displaying Keyboard.&quot; &lt;&lt; std::endl;
    }
    void visit(Monitor &amp;monitor) override {
        std::cout &lt;&lt; &quot;Displaying Monitor.&quot; &lt;&lt; std::endl;
    }
};

// test
int main(int argc, char *argv[]) {
    {
        Computer computer;
        ComputerPartDisplayVisitor computerPartDisplayVisitor;
        computer.accept(computerPartDisplayVisitor);
    }
    return 0;
}
</code></span></code></pre>
  </div>
</div>
 
    </div>
  </div>
  <div id="footer-background">
    <div id="footer">
      <div class="legal pure-g">
  <div class="pure-u-1 u-sm-1-2">
    <p class="legal-license"><a href="https://beian.miit.gov.cn/#/Integrated/index">浙ICP备2020038748号</a></p>
  </div>
  <div class="pure-u-1 u-sm-1-2">
    <p class="legal-links"><a href="https://github.com/zromyk">GitHub</a></p>
    <p class="legal-copyright">Copyright © 2021 Wei Zhou. 保留所有权利。</p>
  </div>
</div>
    </div>
  </div>
  <!-- <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script> -->
  <script src="/style/html/jquery.min.js"></script>
  <script src='/style/article/latex/latest.js?config=TeX-MML-AM_CHTML'></script>
<!-- <script src="https://cdn.geogebra.org/apps/deployggb.js"></script> -->
<script src="/style/article/deployggb.js"></script>
<!-- <script src="https://apps.bdimg.com/libs/highlight.js/9.1.0/highlight.min.js"></script> -->
<script type="text/javascript">
  // 脚本：navigation 随鼠标移动自动变换宽度
  var element = document.getElementById("navigation"); // 获取要操作的元素
  var elementWidth = parseInt(getComputedStyle(element).width);
  var elementLeft = 0;
  var elementRight = 0;
  element.addEventListener('mouseenter', function (event) { // 添加鼠标按下事件的监听器
    elementLeft = element.getBoundingClientRect().left - 10;
    elementRight = element.getBoundingClientRect().left + elementWidth * 3;
    window.addEventListener('mousemove', resize); // 添加全局的鼠标移动事件的监听器
  });

  function resize(event) {
    var minWidth = elementWidth;
    var maxWidth = elementWidth * 2.5;
    // console.log(elementLeft, event.clientX, elementRight, event.clientX - elementLeft + elementWidth / 2);
    if (elementLeft <= event.clientX && event.clientX <= elementRight) {
      var width = event.clientX - elementLeft + elementWidth / 2;
      width = Math.min(width, maxWidth);
      width = Math.max(width, minWidth);
      element.style.width = width + 'px'; // 设置新的宽度样式属性
    }
    else {
      element.style.width = elementWidth + 'px'; // 设置新的宽度样式属性
      stopResize();
    }
  }

  function stopResize() {
    element.style.width = elementWidth + 'px'; // 设置新的宽度样式属性
    // console.log("stopResize", elementLeft, event.clientX, elementRight, event.clientX - elementLeft + elementWidth / 2);
    window.removeEventListener('mousemove', resize); // 移除鼠标移动事件的监听器
  }
</script>
<script src="/style/article/highlight/highlight.min.js"></script>
<script type="text/javascript">
  // 脚本：code语法高亮
  hljs.initHighlightingOnLoad();
</script>
<script>
  function animateByNav() {
    $("html").animate({
        scrollTop: ($(event.target.hash).offset().top - 52)
    }, 300);
  };
</script>
<script src="/style/article/pell-1.0.6/dist/pell.js"></script>
<script>
  // 脚本：自由编辑页面
  var editor = window.pell.init({
    element: document.getElementById('editor'),
    defaultParagraphSeparator: 'p',
    onChange: function(html) {
        document.getElementById('text-output').innerHTML = html
        document.getElementById('html-output').textContent = html
    }
  });

  function markdownEditor() {
    var articles = document.getElementById('content-articles-markdown');
    if (articles.getAttribute("contenteditable") == "true") {
        articles.setAttribute("contenteditable", "false");
        document.getElementById("content-articles-markdownEditor").style.display = "none"; //隐藏
        document.getElementById("button-markdownEditor").innerHTML = "启用编辑";
    } else {
        articles.setAttribute("contenteditable", "true");
        document.getElementById("content-articles-markdownEditor").style.display = ""; //显示
        document.getElementById("button-markdownEditor").innerHTML = "关闭编辑";
    }
  };

  function save() {
      window.alert("保存成功");
  };
</script>

</body>
</html>
